package com.mine.yyb.common.utils.email;

import java.util.Date;
import java.util.Properties;

import javax.mail.Address;
import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.Multipart;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;
import javax.mail.internet.MimeUtility;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.mine.yyb.common.utils.exception.MineErrorCode;
import com.mine.yyb.common.utils.exception.MineException;

/**
 * 
 * <pre>
 * <一句话功能简述>
 * 发件人
 * <功能详细描述>
 * </pre>
 * 
 * @author 彭海明
 * @version [版本号, 2015年5月15日]
 * @see [相关类/方法]
 * @since [产品/模块版本]
 */
public class MineMailSender
{
    /** log 日志 */
    private static final Logger logger = LoggerFactory.getLogger(MineMailSender.class);
    
    /** 字符集UTF-8 */
    private String ENCODE_CHARSET = "UTF-8";
    
    /** 编码格式 */
    private String ENCODING = "B";
    
    // 发送邮件的session
    private Session sendMailSession = null;
    
    // 创建邮件发送者地址
    private Address fromAddress = null;
    
    public MineMailSender(MineEmailConfig mineEmailConfig)
    {
        try
        {
            logger.info(mineEmailConfig.toString());
            
            // 初始化邮箱配置
            Properties emailProperty = new Properties();
            emailProperty.put("mail.smtp.host", mineEmailConfig.getMailServerHost());
            emailProperty.put("mail.smtp.port", mineEmailConfig.getMailServerPort());
            emailProperty.put("mail.smtp.auth", mineEmailConfig.isValidate() ? "true" : "false");
            emailProperty.put("mail.smtp.starttls.enable", "true");
            emailProperty.put("mail.smtp.ssl.trust", mineEmailConfig.getMailServerHost());

            // 需要身份认证，则创建一个密码验证器
            if (mineEmailConfig.isValidate())
            {
                MineEmailAuthenticator authenticator =
                    new MineEmailAuthenticator(mineEmailConfig.getUserName(), mineEmailConfig.getPassword());
                
                // 创建一个需要密码验证器的session
                sendMailSession = Session.getDefaultInstance(emailProperty, authenticator);
            }
            else
            {
                // 创建一个不需要密码验证器的session
                sendMailSession = Session.getDefaultInstance(emailProperty);
            }
            
            // 实例化发送者的消息
            fromAddress = new InternetAddress(mineEmailConfig.getSenderAddress());
            
            logger.info("Init mail is successful");
        }
        catch (Exception e)
        {
            logger.error("Init mail is fail");
            logger.error(MineErrorCode.ERROR_EMAIL_INIT_FAIL.name(), e);
        }
    }
    
    /**
     * 
     * <pre>
     * <一句话功能简述>
     * 发送html格式邮件
     * <功能详细描述>
     * 根据CcpMailVO信息封装发送邮件对象，发送邮件主要是通过后台线程发送
     * </pre>
     * 
     * @param mineMailVO 邮件信息
     * @throws MineException 
     * @see [类、类#方法、类#成员]
     */
    public void sendHtmlMail(final MineMailVO mineMailVO) throws MineException
    {
        if (mineMailVO == null || StringUtils.isEmpty(mineMailVO.getEmailAddress())
            || StringUtils.isEmpty(mineMailVO.getEmailSubject()) 
            || StringUtils.isEmpty(mineMailVO.getEmailContent()))
        {
            throw new MineException(MineErrorCode.ERROR_EMAIL_PARAMS_FAIL);
        }
        
        new Thread("CcpMailThread")
        {
            public void run()
            {
                try
                {
                    logger.info(mineMailVO.toString());
                    
                    // 根据session创建一个邮件消息
                    Message mailMessage = new MimeMessage(sendMailSession);
                    
                    // 设置邮件消息的发送者
                    mailMessage.setFrom(fromAddress);
                    
                    // 创建邮件的接收者地址，并设置到邮件消息中
                    Address to = new InternetAddress(mineMailVO.getEmailAddress());
                    
                    // Message.RecipientType.TO属性表示接收者的类型为TO
                    mailMessage.setRecipient(Message.RecipientType.TO, to);
                    
                    // 设置邮件消息的主题，解决邮件主题乱码问题
                    mailMessage.setSubject(MimeUtility.encodeText(mineMailVO.getEmailSubject(), ENCODE_CHARSET, ENCODING));
                    
                    // 设置邮件消息发送的时间
                    mailMessage.setSentDate(new Date());
                    
                    // MiniMultipart类是一个容器类，包含MimeBodyPart类型的对象
                    Multipart mainPart = new MimeMultipart();
                    
                    // 创建一个包含HTML内容的MimeBodyPart
                    BodyPart html = new MimeBodyPart();
                    
                    // 设置HTML内容
                    html.setContent(mineMailVO.getEmailContent(), mineMailVO.getContentCharset());
                    
                    mainPart.addBodyPart(html);
                    
                    // 将MiniMultipart对象设置为邮件内容
                    mailMessage.setContent(mainPart);
                    
                    // 发送邮件
                    Transport.send(mailMessage);
                    
                    logger.info("Send mail is successful.");
                }
                catch (Exception e)
                {
                    logger.error(MineErrorCode.ERROR_EMAIL_SEND_FAIL.name(), e);
                }
            };
            
        }.start();
    }
    
}
